package br.unifor.util.cluster.jgcs;

import java.io.Serializable;
import java.net.SocketAddress;
import java.util.Vector;

import net.sf.jgcs.ControlSession;
import net.sf.jgcs.DataSession;
import net.sf.jgcs.Protocol;
import net.sf.jgcs.Service;
import net.sf.jgcs.membership.MembershipListener;

/**
 * An interface of the JGCS distributed tree.
 * @author Leandro Sales
 */
public interface IDistributedTree {

    void start() throws Exception;

    void start(long timeout) throws Exception;

    void stop();

    void add(String fqn);

    void add(String fqn, Serializable element);

    /** resets an existing node, useful after a merge when you want to tell other
     *  members of your state, but do not wish to remove and then add as two separate calls */
    void reset(String fqn, Serializable element);

    void remove(String fqn);

    void add(String fqn, Serializable element, int timeout);

    /** resets an existing node, useful after a merge when you want to tell other
     *  members of your state, but do not wish to remove and then add as two separate calls */
    void reset(String fqn, Serializable element, int timeout);

    void remove(String fqn, int timeout);

    boolean exists(String fqn);

    Serializable get(String fqn);

    void set(String fqn, Serializable element);

    void set(String fqn, Serializable element, int timeout);

    void addDistributedTreeListener(
            DistributedTreeListener distributedTreeListener);

    void removeDistributedTreeListener(DistributedTreeListener distributedTreeListener);

    void addViewListener(ViewListener listener);

    void removeViewListener(ViewListener listener);

    ControlSession getControlSession();
    DataSession getDataSession();
    Protocol getProtocol();
    Service getService();

    SocketAddress getLocalAddress();

    Vector<String> getChildrenNames(String fqn);

    public interface DistributedTreeListener {
        void nodeAdded(String fqn, Serializable element);

        void nodeRemoved(String fqn);

        void nodeModified(String fqn, Serializable old_element, Serializable new_element);
    }

    public interface ViewListener {
        void viewChange(Vector<SocketAddress> new_mbrs, 
        				Vector<SocketAddress> old_mbrs);
    }
    
    public void setMembershipListener(MembershipListener membershipListener);
}
